home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 15 code / Floating Windows / Floating Windows Code / Shell Code / eventHandler.c < prev    next >
Encoding:
Text File  |  1995-07-17  |  11.8 KB  |  444 lines  |  [TEXT/MMCC]

  1. /*    MPW C Application skeleton by Dean Yu    */
  2. /*    Event handling routines                    */
  3.  
  4. // If the interfaces aren't included yet, do the standard includes. Otherwise, precompiled headers
  5. // have been loaded already, thank you very much
  6. #ifndef __TYPES__
  7.     #include <Types.h>
  8.     #include <AppleEvents.h>
  9.     #include <Desk.h>
  10.     #include <Dialogs.h>
  11.     #include <Editions.h>
  12.     #include <Events.h>
  13.     #include <Menus.h>
  14.     #include <SegLoad.h>
  15.     #include <TextUtils.h>
  16.     #include <ToolUtils.h>
  17.     #include <Windows.h>
  18. #endif
  19.  
  20. // Not in Metrowerks default precompiled headers
  21. #include <Editions.h>
  22.  
  23. #include "FloaterSample.h"
  24. #include "appleEventHandlers.h"
  25. #include "eventHandler.h"
  26. #include "menuDispatch.h"
  27.  
  28. /*    Routine prototypes    */
  29.  
  30. void    DoMouseEvent (EventRecord *event);
  31. void    DoKeyEvent (EventRecord *event);
  32. void    DoActivateEvent(EventRecord *event);
  33. void    DoUpdateEvent (EventRecord *event);
  34. void    DrawWindowContent(Boolean doFill);
  35. void    DoOSEvent(EventRecord *event);
  36. void    DoHighLevelEvent(EventRecord *event);
  37. void    HandleGenericHighLevelEvent(EventRecord *event);
  38.  
  39. /* Globals */
  40.     
  41. extern Boolean    gDone;                            /* Set to true if user selects Quit */
  42. extern Boolean    gInBackground;                    /* Set to true if app is switched into background */
  43. extern short    gTimeToDialogDismissal;
  44. extern Rect        gDragArea;                        /* Area in which a window can be dragged */
  45. extern Rect        gGrowBounds;                    /* Min and maximum size a window can be sized to */
  46. extern Boolean    gNotificationPosted;            // True if a notification was posted
  47. extern NMRec    gNotificationRec;                // the notification record
  48. extern ActivateHandlerUPP    gActivateEventHandler;
  49.  
  50. /*
  51.     Fatal error alert routine.
  52.     If an error occurs, this routine is called with the error message number
  53.     that message is pulled from the error STR# resource, and displayed in an
  54.     alert.  The application then quits when the user clicks the “OK” button.
  55. */
  56. void        FatalErrorAlert(short    errID)
  57. {
  58.     short    alrtItem;
  59.     Str255    errString;
  60.     
  61.     GetIndString(errString, rFatalErrorStringsID, errID);
  62.     ParamText(errString, nil, nil, nil);
  63.     alrtItem = Alert(rFatalErrorAlertID, nil);
  64.     ExitToShell();
  65. }
  66.  
  67. void    EventLoop()
  68. {
  69.     EventRecord    event;
  70.     DialogPtr    theDialog;
  71.     short        itemHit;
  72.     Boolean        gotEvent;
  73.     ProcessSerialNumber    currentPSN, frontPSN;
  74.     OSErr        getFrontProcessResult, getCurrentProcessResult;
  75.     Boolean        isFrontProcess = false;
  76.     
  77.     // Set gInBackground appropriately
  78.     // Compare this process and the front process
  79.     getFrontProcessResult = GetFrontProcess(&frontPSN);
  80.     getCurrentProcessResult = GetCurrentProcess(¤tPSN);
  81.     if ((getFrontProcessResult == noErr) && (getCurrentProcessResult == noErr))
  82.         SameProcess(&frontPSN, ¤tPSN, &isFrontProcess);
  83.     gInBackground = !isFrontProcess;
  84.     
  85.     gDone = false;
  86.     
  87.     do {
  88.         gotEvent = WaitNextEvent(everyEvent, &event, 15, nil);
  89.         if (gotEvent) {
  90.             if (!IsDialogEvent(&event))
  91.                 HandleEvent(&event);
  92.             else {
  93.                 DialogSelect(&event, &theDialog, &itemHit);
  94.                 if ((itemHit == ok) || (itemHit == cancel))
  95.                     DisposeFindDialog();
  96.                 
  97.                 if (event.what == osEvt)
  98.                     DoOSEvent(&event);
  99.             }
  100.         }
  101.         
  102.         // If we’re in the background, and the find dialog is up, close it after
  103.         // a time to demonstrate what should happen to floating windows in the background.
  104.         
  105.         if (gInBackground && (gTimeToDialogDismissal > 0)) {
  106.             --gTimeToDialogDismissal;
  107.             if (gTimeToDialogDismissal == 0)
  108.                 DisposeFindDialog();
  109.         }
  110.     } while (!gDone);
  111.     ExitToShell();
  112. }
  113.  
  114. void    HandleEvent(EventRecord    *event)
  115. {
  116.     switch (event->what) {
  117.         case mouseDown:            DoMouseEvent(event);
  118.                                 break;
  119.         case keyDown:
  120.         case autoKey:            DoKeyEvent(event);
  121.                                 break;
  122.         case activateEvt:        DoActivateEvent(event);
  123.                                 break;
  124.         case updateEvt:            DoUpdateEvent(event);
  125.                                 break;
  126.         case osEvt:                DoOSEvent(event);
  127.                                 break;
  128.         case kHighLevelEvent:    DoHighLevelEvent(event);
  129.                                 break;
  130.                                                         
  131.     }
  132. }
  133.  
  134. void    DoMouseEvent(EventRecord *event)
  135. {
  136.     short        part;
  137.     long        growResult;
  138.     WindowRef    whichWindow;
  139.     WindowRef    frontWindow;
  140.     
  141.     part = FindWindow(event->where, &whichWindow);
  142.     switch (part) {
  143.         case inDesk:        break;
  144.         case inMenuBar:     DoMenuCommand(MenuSelect(event->where));
  145.                             break;
  146.         case inSysWindow:    SystemClick(event, (WindowPtr)whichWindow);
  147.                             break;
  148.         case inContent:        frontWindow = FrontWindow();
  149.                             if (WindowIsModal(frontWindow) &&
  150.                                 (whichWindow != frontWindow))
  151.                                     SysBeep(1);
  152.                             else if (whichWindow != frontWindow)
  153.                                     SelectReferencedWindow(whichWindow);
  154.                             else // testing, testing
  155.                             {
  156.                                 Point            localPt;
  157.                                 ControlHandle    cHandle;
  158.                                 short            inWhat;
  159.                                 
  160.                                 // might be our test modal
  161.                                 SetPort((GrafPtr)GetWindowPort(whichWindow));
  162.                                 localPt = event->where;
  163.                                 GlobalToLocal(&localPt);
  164.                                 inWhat = FindControl(localPt, whichWindow, &cHandle);
  165.                                 if(inWhat == inButton && GetControlReference(cHandle) == 'DAVE')
  166.                                 {
  167.                                     if(TrackControl(cHandle, localPt, nil))
  168.                                     {
  169.                                         DisposeWindowReference(whichWindow);
  170.                                         ActivateFloatersAndFirstDocumentWindow();
  171.                                     }
  172.                                 }
  173.                             }
  174.                             break;
  175.         case inDrag:        frontWindow = FrontWindow();
  176.                             if (WindowIsModal(frontWindow) &&
  177.                                 (whichWindow != frontWindow))
  178.                                     SysBeep(1);
  179.                             else
  180.                                 DragReferencedWindow(whichWindow, event->where, &gDragArea);
  181.                             break;
  182.         case inGrow:        growResult = GrowWindow(whichWindow, event->where, &gGrowBounds);
  183.                                 SizeWindow(whichWindow, growResult & 0x0000FFFF, (growResult & 0xFFFF0000) >> 16, true);
  184.                             break;
  185.         case inGoAway:        if (TrackGoAway(whichWindow, event->where)) {
  186.                                 
  187.                                 // All these bizarre cases are for testing puposes...
  188.                                 if(event->modifiers & optionKey)
  189.                                 {
  190.                                     // Hide then show the window
  191.                                     HideReferencedWindow(whichWindow);
  192.                                     ShowReferencedWindow(whichWindow);
  193.                                 }
  194.                                 else if(event->modifiers & cmdKey)
  195.                                 {
  196.                                     WindowRef    next = GetNextVisibleWindow(whichWindow);
  197.                                     
  198.                                     // Hide this window, then the next
  199.                                     HideReferencedWindow(whichWindow);
  200.                                     HideReferencedWindow(next);
  201.                                 }
  202.                                 else if(event->modifiers & shiftKey)
  203.                                 {
  204.                                     long    dum;
  205.                                     DeactivateFloatersAndFirstDocumentWindow();
  206.                                     Delay(60, &dum);
  207.                                     ActivateFloatersAndFirstDocumentWindow();
  208.                                 }
  209.                                 else if(event->modifiers & controlKey)
  210.                                 {
  211.                                     long    dum;
  212.                                     SuspendFloatingWindows();
  213.                                     Delay(60, &dum);
  214.                                     ResumeFloatingWindows();
  215.                                 }
  216.                                 else
  217.                                 {
  218.                                     // This is just in case multiple windows share the same
  219.                                     //  WindowPic, like when the program is started up with the 
  220.                                     // mopuse button down so that the test windows are up
  221.                                     SetWindowPic(whichWindow, nil);
  222.                                     
  223.                                     // Dispose of the window
  224.                                     DisposeWindowReference(whichWindow);
  225.                                 }
  226.                                 
  227.                                 if(FrontNonFloatingWindow() == nil)
  228.                                     DisableItem(GetMHandle(rFileMenuID), kCloseItem);
  229.                             }
  230.                             break;
  231.         case inZoomIn:
  232.         case inZoomOut:        break;
  233.     }
  234. }
  235.  
  236. void    DoKeyEvent(EventRecord *event)
  237. {
  238.     long    theKey;
  239.     
  240.     theKey = event->message & charCodeMask;
  241.     if ((event->modifiers & cmdKey) && (event->what == keyDown))
  242.         DoMenuCommand(MenuKey((char) theKey));
  243. }
  244.  
  245. void DoActivateEvent(EventRecord *event)
  246. {
  247.     Boolean    activating = false;
  248.     
  249.     if (GetWindowKind((WindowRef) event->message) != dialogKind) {
  250.         if (event->modifiers & activeFlag)
  251.             activating = true;
  252.         
  253.         DebugStr("\pGot activate from event loop.");
  254.         
  255.         ActivateEventHandler((WindowRef) event->message, activating);
  256.     }
  257. }
  258.  
  259. pascal void ActivateEventHandler(WindowRef theWindow, Boolean activateWindow)
  260. {
  261.     GrafPtr    currentPort;
  262.     
  263.     GetPort(¤tPort);
  264.     SetPort((GrafPtr) theWindow);
  265.     
  266.     DrawWindowContent(activateWindow);
  267.     
  268.     if (activateWindow == false)
  269.         SetPort(currentPort);
  270. }
  271.  
  272. pascal void    RecordingFloaterActivateHandler(WindowRef theWindow, Boolean activateWindow)
  273. {
  274.     GrafPtr        currentPort;
  275.     PicHandle    recordingControlsPicture;
  276.     short        whichPicture;
  277.     
  278.     GetPort(¤tPort);
  279.     SetPort((GrafPtr) theWindow);
  280.     
  281.     if (activateWindow == true)
  282.         whichPicture = 128;
  283.     else
  284.         whichPicture = 129;
  285.     recordingControlsPicture = GetPicture(whichPicture);
  286.     
  287.     DrawPicture(recordingControlsPicture, &((**recordingControlsPicture).picFrame));
  288.     SetWindowPic(theWindow, recordingControlsPicture);
  289.     
  290.     if (activateWindow == false)
  291.         SetPort(currentPort);
  292. }
  293.  
  294. pascal void    ToolsFloaterActivateHandler(WindowRef theWindow, Boolean activateWindow)
  295. {
  296.     GrafPtr        currentPort;
  297.     PicHandle    toolsPicture;
  298.     short        whichPicture;
  299.     
  300.     GetPort(¤tPort);
  301.     SetPort((GrafPtr) theWindow);
  302.     
  303.     if (activateWindow == true)
  304.         whichPicture = 130;
  305.     else
  306.         whichPicture = 131;
  307.     toolsPicture = GetPicture(whichPicture);
  308.     
  309.     DrawPicture(toolsPicture, &((**toolsPicture).picFrame));
  310.     SetWindowPic( theWindow, toolsPicture);
  311.     
  312.     if (activateWindow == false)
  313.         SetPort(currentPort);
  314. }
  315.  
  316. pascal void    TestFloaterActivateHandler(WindowRef theWindow, Boolean activateWindow)
  317. {
  318.     GrafPtr        currentPort;
  319.     PicHandle    davePicture;
  320.     short        whichPicture;
  321.     
  322.     GetPort(¤tPort);
  323.     SetPort((GrafPtr) theWindow);
  324.     
  325.     if (activateWindow == true)
  326.         whichPicture = 132;
  327.     else
  328.         whichPicture = 133;
  329.     davePicture = GetPicture(whichPicture);
  330.     
  331.     DrawPicture(davePicture, &((**davePicture).picFrame));
  332.     SetWindowPic(theWindow, davePicture);
  333.     
  334.     if (activateWindow == false)
  335.         SetPort(currentPort);
  336. }
  337.  
  338. void    DoUpdateEvent(EventRecord *event)
  339. {
  340.     WindowRef    theWindow = (WindowRef)event->message;
  341.     
  342.     SetPortWindowPort(theWindow);
  343.     BeginUpdate(theWindow);
  344.         if(GetExtWRefCon(theWindow) == 'DAVE')
  345.             DrawControls(theWindow);
  346.         else
  347.         {
  348.         EraseRect(&(GetWindowPort(theWindow)->portRect));
  349.         DrawWindowContent(IsWindowHilited((WindowRef)theWindow));
  350.         }
  351.     EndUpdate(theWindow);
  352. }
  353.  
  354. void    DrawWindowContent(Boolean doFill)
  355. {
  356.     Rect    tempRect;
  357.  
  358.     SetRect(&tempRect, 5, 5, 50, 50);
  359.     
  360.     if (doFill) // == true) see notes in WindowExtensions.c
  361.         FillRect(&tempRect, &(qd.black));
  362.     else {
  363.         FrameRect(&tempRect);
  364.         InsetRect(&tempRect, 1, 1);
  365.         EraseRect(&tempRect);
  366.     }
  367. }
  368.  
  369. void    DoOSEvent(EventRecord *event)
  370. {
  371.     switch ((event->message >> 24) & 0xFF) {
  372.         case mouseMovedMessage:        break;
  373.         case suspendResumeMessage:    if (event->message & resumeFlag) {
  374.                                         gInBackground = false;
  375.                                         gTimeToDialogDismissal = 0;
  376.                                         DisableItem(GetMHandle(rEditMenuID), 0);
  377.                                         DrawMenuBar();
  378.                                         ResumeFloatingWindows();
  379.                                         SetCursor(&qd.arrow);
  380.                                         // Remove notification if it exists
  381.                                         if(gNotificationPosted)
  382.                                         {
  383.                                             NMRemove(&gNotificationRec);
  384.                                             gNotificationPosted = false;
  385.                                         }
  386.                                     }
  387.                                     else {
  388.                                         gInBackground = true;
  389.                                         if (GetWindowKind(FrontWindow()) == dialogKind)
  390.                                             gTimeToDialogDismissal = 5;
  391.                                         SuspendFloatingWindows();
  392.                                     }
  393.                                     break;
  394.     }
  395. }
  396.  
  397.  
  398. /*    Handle high level events */
  399.  
  400. void    DoHighLevelEvent(EventRecord *event)
  401. {
  402.     OSErr    AEProcessResult;
  403.     
  404.     switch    (event->message) {
  405.         case kCoreEventClass:    AEProcessResult = AEProcessAppleEvent(event);    /*    Handle core AppleEvents */
  406.                                 break;
  407.         case rSectionType:        break;                                            /*    Handle Edition Manager AppleEvents */
  408.         default:                HandleGenericHighLevelEvent(event);                /*    Other high level events */
  409.                                 break;
  410.     }
  411. }
  412.  
  413. void    HandleGenericHighLevelEvent(EventRecord *event)
  414. {
  415.     TargetID    eventSenderInfo;
  416.     unsigned    long eventIdentifier;
  417.     Ptr            dataBuffer;
  418.     unsigned    long dataSize;
  419.     OSErr    HLEventError;
  420.     
  421.     dataSize = 0;
  422.     dataBuffer = nil;
  423.     HLEventError = AcceptHighLevelEvent(&eventSenderInfo, &eventIdentifier, dataBuffer, &dataSize);
  424.     
  425.     /*
  426.         Since we don’t know how much data is coming in, call AcceptHighLevelEvent once to
  427.         find out how much data was sent, then use create a new buffer large enough to hold
  428.         all the data, then call AcceptHighLevelEvent again to get the data.
  429.     */
  430.     
  431.     if (HLEventError == bufferIsSmall) {
  432.         dataBuffer = NewPtr(dataSize);
  433.         HLEventError = AcceptHighLevelEvent(&eventSenderInfo, &eventIdentifier, dataBuffer, &dataSize);
  434.     }
  435.         
  436.     /*    Dispatch the high level event to the proper routine depending on the message class */
  437.     
  438.     switch    (event->message) {
  439.     }
  440.     
  441.     if (dataBuffer)
  442.         DisposPtr(dataBuffer);
  443. }
  444.